home *** CD-ROM | disk | FTP | other *** search
/ CGI How-To / CGI HOW-TO.iso / chap6 / 6_8 / newd_c / newdata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-15  |  4.6 KB  |  228 lines

  1.  
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include "cgilib.h"
  6.  
  7. extern char **environ;
  8.  
  9. char **copyEnvironment(char **environment)
  10. {
  11.     int numEnvvar = 0;
  12.     const char *tmp;
  13.     char **newEnv;
  14.     
  15.     /* Loop through the array */
  16.     
  17.     for( tmp = *environment; '\0' != *tmp; tmp += strlen(tmp)+1 )
  18.     {
  19.         /* Count the number of env var */
  20.         numEnvvar++;
  21.     }
  22.     
  23.     numEnvvar++; /* for the null */
  24.     
  25.     newEnv = malloc(numEnvvar * sizeof(char *));
  26.     
  27.     /* Depending on your machine, you might use memcopy here */
  28.     bcopy(environment,newEnv,(sizeof(char *) * numEnvvar));
  29.     
  30.     return newEnv;
  31. }
  32.  
  33. void setEnvVar(char ***environment, const char *envName, const char * newValue)
  34. {
  35.     if(newValue && envName)
  36.     {
  37.         char *tmp;
  38.         size_t length;
  39.         int gotIt = 0, numEnvvar = 0;
  40.         
  41.         length = strlen(envName);
  42.         
  43.         /* Loop through the array */
  44.         
  45.         for( tmp = **environment; '\0' != *tmp; tmp += strlen(tmp)+1 )
  46.         {
  47.             /* Count the number of env var */
  48.             numEnvvar++;
  49.             
  50.             /* Check if this is the right env variable */
  51.             if ( !(strncmp( tmp, envName, length))
  52.                 &&( '=' == tmp[ length ] ))
  53.             {
  54.                 int newSize;
  55.                 
  56.                 /* Calc the new size, include space for the '=' */
  57.                 newSize = strlen(envName) + strlen(newValue) + 2;
  58.                 
  59.                 /*free(tmp);*/
  60.                 
  61.                 tmp = malloc(sizeof(char) * newSize);
  62.                 
  63.                 strcpy(tmp,envName);
  64.                 strcat(tmp,"=");
  65.                 strcat(tmp,newValue);
  66.                 (*environment)[numEnvvar-1] = tmp;
  67.                 gotIt = 1;
  68.                 break;
  69.             }
  70.         }
  71.         
  72.         numEnvvar++; /* for the null */
  73.         
  74.         if(!gotIt)
  75.         {
  76.             int newSize;
  77.             
  78.             /* Calc the new size, include space for the '=' */
  79.             newSize = strlen(envName) + strlen(newValue) + 2;
  80.             
  81.             tmp = malloc(sizeof(char) * newSize);
  82.             
  83.             strcpy(tmp,envName);
  84.             strcat(tmp,"=");
  85.             strcat(tmp,newValue);
  86.                 
  87.              /* Grow the array by 1*/
  88.             *environment = realloc(*environment,sizeof(char *)*(numEnvvar+1));
  89.             (*environment)[numEnvvar-1] = tmp;
  90.             (*environment)[numEnvvar] = (char *) 0;
  91.         }
  92.     }
  93. }
  94.  
  95. void main(int argc, char *argv[])
  96. {
  97.     /* Variables for the data. */
  98.     
  99.     Dictionary dataDict;
  100.     String data = 0;
  101.     const char *theScript = (char *)0,*choice = (char *)0;
  102.     int pipeTo[2];
  103.     int pidChild = -1;
  104.     char buffer[16];
  105.     char **newEnviron;
  106.     int numFds,fd;
  107.     
  108.     /*
  109.      * Get the CGI data from the CGI library
  110.      */
  111.     dataDict = readParse();
  112.     
  113.     /* figure out which radio button was pressed. */
  114.     
  115.     choice = dict_valueForKey(dataDict,"choice");
  116.     
  117.     if(choice)
  118.     {
  119.         if(!strcmp(choice,"vars"))
  120.         {
  121.             theScript = "envvar";
  122.         }
  123.         else
  124.         {
  125.             theScript = "formdata";
  126.         }
  127.     }
  128.     else
  129.     {
  130.         theScript = "formdata";
  131.     }
  132.     
  133.     /* Add some new data */
  134.     data = string_alloc(16);
  135.     string_setStringValue(data,"Some New Data");
  136.     dict_setValueForKey(dataDict,"NEW",string_copyValue(data));
  137.     string_free(data);
  138.  
  139.     /* Create the encoded data to send to the child */
  140.  
  141.     data = encodeDictionary(dataDict);
  142.  
  143.     /* Set up the environment */
  144.     
  145.     /* Copy the gloval environment */
  146.     newEnviron = copyEnvironment(environ);
  147.     
  148.     /* Reset the relevent env. var. for the child */
  149.     sprintf(buffer,"POST");
  150.     setEnvVar(&newEnviron,"REQUEST_METHOD",buffer);
  151.     
  152.     sprintf(buffer,"%d",string_length(data));
  153.     setEnvVar(&newEnviron,"CONTENT_LENGTH",buffer);
  154.     
  155.     /********** Fork the child process ************/
  156.     
  157.     if(theScript)
  158.     {
  159.         /* Create a set of pipes, on will be used to read,the other to write */
  160.         
  161.         if(pipe(pipeTo) < 0)
  162.         {
  163.             fprintf(stderr,"Error creating pipes to subprocess.");
  164.             exit(1);
  165.         }
  166.         
  167.         fflush(stdout);/*flush all output streams */
  168.         
  169.         /* Call fork, use vfork if it is available */
  170.         switch (pidChild = vfork())
  171.         {
  172.             case -1:    /* error */
  173.                 
  174.                 fprintf(stderr,"Error starting UNIX vfork of subprocess.");
  175.                 break;
  176.                 
  177.             case 0:    /* child */
  178.                 
  179.                 /* Use the first pipe as stdin */
  180.                 dup2(pipeTo[0], 0);
  181.                 
  182.                 close(pipeTo[0]);
  183.                 
  184.                 /* Call exec */
  185.                 execle(theScript,theScript, NULL,newEnviron);
  186.         
  187.                 /* We should never get here, because of the exec. */
  188.                 perror("vfork:forkingCGI (child)"); 
  189.                 
  190.                 exit(1);
  191.                 
  192.             default:    /* parent */
  193.                 
  194.                 /* Close the reading pipe, we dont need it */
  195.                 close(pipeTo[0]);
  196.                 
  197.                 /* Write the data to the child */
  198.                 if(data && data->string)
  199.                 {
  200.                   int len,remaining,wrote = 0;
  201.  
  202.                   len = string_length(data) * sizeof(char);
  203.                   remaining = len;
  204.                   
  205.                   while(remaining && (wrote >= 0))
  206.                     {
  207.                       wrote = write(pipeTo[1], (char *)(data->string) + (len-remaining), remaining);
  208.                       remaining -= wrote;
  209.                     }
  210.  
  211.                 }
  212.                 
  213.                 /* Wait for the child to execute */
  214.                 if((pidChild)&&(wait((union wait *)0) !=pidChild))
  215.                 {
  216.                     /* Close the remaining pipe */
  217.                     close(pipeTo[1]);
  218.                 }
  219.         }
  220.     }
  221.     
  222.     dict_free(dataDict);
  223.     string_free(data);
  224.     
  225.     /* End the program */
  226.     exit(0);
  227. }
  228.